#ifndef CFormH
#define CFormH

#include "Outils.h"
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Extctrls.hpp>

#define TAG_BOUTON_PRINT   200
#define TAG_BOUTON_PREVIEW 201
#define IS_BOUTON_PRINT(Sender) (((TComponent *)Sender)->Tag == TAG_BOUTON_PRINT)
#define IS_BOUTON_PREVIEW(Sender) (((TComponent *)Sender)->Tag == TAG_BOUTON_PREVIEW)

enum FORM_POSITION { posDesigned      = poDesigned,
                     posScreenCenter  = poScreenCenter,
                     posInitFromTForm = 100,
                     posParentCenter  = 101,
                     posInherrited    = 102   };

class CDataExchange;
class PACKAGE_OUTILS CEICForm : public TForm
{
 private:
  typedef TForm inherited;
  bool               m_bAutoCenterY;
  int                m_ScreenTag;
  bool               m_bDataModified;       // TRUE si les données d'un control ont été modifiées pendant un UpdateData()
  bool               m_bTabEnter;           // TRUE si la toucher 'Entree' permet de passer d'un composant à l'autre
  enum FORM_POSITION m_ePosition;           // Position de la fenêtre sur l'écran
  //TNotifyEvent       m_pfnOnDesignedCreate; // Méthode  "OnCreate"  liée à la conception de la fiche
  bool               m_bGridInsert;
  Graphics::TBitmap *m_bmpBackground;

    //TKeyPressEvent m_OnKeyPress;
    TNotifyEvent   m_OnPrint;
    TNotifyEvent   m_OnPreview;
    TNotifyEvent   m_OnCustomSelect;
    TDrawItemEvent m_OnComboDrawItem;

    void __fastcall SetPosition( enum FORM_POSITION ePosition = posInitFromTForm);
    void __fastcall SetOnPreview( TNotifyEvent pEvent) { m_OnPreview = pEvent; };
    void __fastcall SetOnPrint  ( TNotifyEvent pEvent) { m_OnPrint   = pEvent; };

  void __fastcall Init();

 protected:
   void __fastcall EvOnKeyPress(/*TObject *Sender,*/ char &Key);
   DYNAMIC void __fastcall KeyPress( char &cKey);

   virtual void __fastcall AfterConstruction( void);
   void __fastcall WMEraseBackground( TMessage &eMessage);
   void __fastcall SetTabEnter( bool bValue);

   BEGIN_MESSAGE_MAP
     MESSAGE_HANDLER( WM_ERASEBKGND, TMessage, WMEraseBackground)
   END_MESSAGE_MAP( TForm)
  virtual void __fastcall DoDataExchange( CDataExchange* pdx);

 public:
          __fastcall  CEICForm(TComponent* Owner = NULL);
          __fastcall  CEICForm(HWND Owner);
  virtual __fastcall ~CEICForm( void);
         bool __fastcall UpdateData( bool bUpdateForm = false);
  inline bool __fastcall UpdateForm( void) { return( UpdateData( true)); }
  void __fastcall RecentrerControls();
  void __fastcall AfficherPremiereFille();
  //bool            TabEnter;            // TRUE (par défaut) si l'on veut passer au controle suivant avec ENTRER et FALSE sinon (rajouté par DavidR)
  // Nouvelles propriétés
  __property int  ScreenTag    = { read = m_ScreenTag     , write = m_ScreenTag     };
  __property bool DataModified = { read = m_bDataModified , write = m_bDataModified };
  __property bool GridInsert   = { read = m_bGridInsert   , write = m_bGridInsert   };
  __property bool TabEnter     = { read = m_bTabEnter     , write = SetTabEnter     };
  __property Graphics::TBitmap *Background = { read=m_bmpBackground };
  __property enum FORM_POSITION EICPosition = { read=m_ePosition , write=SetPosition };
  virtual int __fastcall ShowModal(void);

 __published:
  __property bool AutoCenterY  = { read = m_bAutoCenterY  , write = m_bAutoCenterY , default = true};
  // Evénements redéfinis
  __property TNotifyEvent   OnCustomSelect = { read = m_OnCustomSelect,      write = m_OnCustomSelect };
  //__property TKeyPressEvent OnKeyPress     = { read=m_OnKeyPress    , write=m_OnKeyPress     };
  __property TDrawItemEvent OnComboDrawItem = { read=m_OnComboDrawItem, write=m_OnComboDrawItem };
  __property TNotifyEvent   OnPreview      = { read=m_OnPreview     , write=SetOnPreview      };
  __property TNotifyEvent   OnPrint        = { read=m_OnPrint       , write=SetOnPrint        };
};
//---------------------------------------------------------------------------
typedef CEICForm CForm;
//---------------------------------------------------------------------------


//////////////////////////
// Classe CDataExchange //
////////////////////////////////////////////////////////////////////////////////
//
//   Cette classe, utilisée via le membre de la classe CForm::DoDataExchange(),
// permet d'échanger des données avec les contrôles d'une fiche de type CForm.
////////////////////////////////////////////////////////////////////////////////
class PACKAGE_OUTILS CDataExchange
{
 private:
  bool         m_bUpdateForm;         // TRUE pour lire les membres et faire une MAJ de la fenêtre; FALSE pour lire les membres depuis la fenêtre
  CEICForm&    m_frm;                 // Fenêtre mère des controls
  TWinControl* m_pLastWinCtrl;        // Dernier control testé dans l'échange
  HWND         m_hwndLastCtrl;        // Handle du dernier control testé dans l'échange
  bool         m_bLastCtrlIsEditable; // TRUE si m_hwndLastCtrl est éditable
  bool         m_bFormIsCanceled;     // TRUE si la fiche est en cours d'annulation (CForm::UpdateData() ne sert qu'à savoir si les données ont changé)
 public:
  __property bool UpdateForm     = { read = m_bUpdateForm};
  __property bool DataModified   = { read = GetModified, write = SetModified};
  __property bool FormIsCanceled = { read = m_bFormIsCanceled};

  inline bool __fastcall GetModified( void)           const { return( m_frm.DataModified);}
  inline void __fastcall SetModified( bool bModified)       { m_frm.DataModified = bModified;}
   __fastcall CDataExchange( CEICForm& frm, bool bUpdateForm);
  HWND __fastcall PrepareControl(         TWinControl* pWinCtrl);
  HWND __fastcall PrepareEditableControl( TWinControl* pWinCtrl);
  void __fastcall Fail( const char* pcszErrBoxMsg); // MAKEINTRESOURCE accepté
}; /* class CDataExchange */


//*****************************************//
// Fonctions d'échange/validation standard //
//*****************************************//
// Ces fonctions sont à utiliser dans le membre CForm::DoDataExchange() //
// Fonctions d'échange //
extern PACKAGE_OUTILS bool        __fastcall DDX_IsChecked( CDataExchange* pdx, TCustomCheckBox* pchk,     bool&       b);
extern PACKAGE_OUTILS AnsiString& __fastcall DDX_Text(      CDataExchange* pdx, TWinControl*     pWinCtrl, AnsiString& str);
extern PACKAGE_OUTILS void        __fastcall DDX_Time(      CDataExchange* pdx, TWinControl*     pWinCtrl, TDateTime&  time); // En affichage seulement
extern PACKAGE_OUTILS int         __fastcall DDX_LBIndex(   CDataExchange* pdx, TCustomListBox*  plb,      int&        nIndex);
extern PACKAGE_OUTILS int         __fastcall DDX_CBIndex(   CDataExchange* pdx, TCustomComboBox* pcb,      int&        nIndex, int eMinIndex = 0, int eInvalidIndex = -1);
extern PACKAGE_OUTILS int         __fastcall DDX_RadioGrp(  CDataExchange* pdx, TRadioGroup*     prgrp,    int&        nItemIndex);

// Fonctions de validation //
#define         DDV_StrNotEmpty( pdx, cstr) DDV_MinStrLen( pdx, cstr, 1)
extern PACKAGE_OUTILS void __fastcall DDV_MinStrLen(       CDataExchange* pdx, const AnsiString& cstr,   int nMinLen   = 1);
extern PACKAGE_OUTILS void __fastcall DDV_MinMaxListIndex( CDataExchange* pdx, int               nIndex, int nMinIndex = 0, int nMaxIndex = 0);
extern PACKAGE_OUTILS void __fastcall DDV_DateNonVide(     CDataExchange* pdx, const TDateTime &Date);

#endif
